<template>
  <div class="progress-display">{{ progress }}%</div>
</template>

<script lang="ts" setup>
  import { ref, onUnmounted, onMounted } from 'vue';

  // 定义props
  const props = defineProps({
    // 是否自动开始动画
    autoStart: {
      type: Boolean,
      default: false,
    },
    // 目标进度值
    targetProgress: {
      type: Number,
      default: 99,
    },
  });

  // 定义emit事件
  const emit = defineEmits<{
    // 动画完成时触发
    finish: [];
  }>();

  // 进度相关状态
  const progress = ref(0);
  const progressTimer = ref<number | null>(null);
  const startTime = ref<number>(0);
  const duration = ref(0); // 动画持续时间（毫秒）

  // 生成随机8-12秒的duration
  const generateRandomDuration = () => {
    return Math.floor(Math.random() * 4000) + 8000; // 8000-12000毫秒
  };

  // 开始进度动画
  const startAnimation = () => {
    // 重置进度
    progress.value = 0;
    startTime.value = Date.now();
    // 生成随机持续时间
    duration.value = generateRandomDuration();

    // 清除之前可能存在的定时器
    if (progressTimer.value) {
      clearInterval(progressTimer.value);
    }

    // 设置定时器，每16ms更新一次（约60fps）
    progressTimer.value = window.setInterval(() => {
      const elapsed = Date.now() - startTime.value;
      const elapsedSeconds = elapsed / 1000;
      const totalSeconds = duration.value / 1000;

      // 使用缓动函数实现粘滞效果
      // 根据总时长按比例分配各阶段时间
      const stage1Time = totalSeconds * 0.2; // 前20%时间
      const stage2Time = totalSeconds * 0.4; // 接下来40%时间
      const stage3Time = totalSeconds * 0.4; // 最后40%时间

      let progressPercent;
      if (elapsedSeconds <= stage1Time) {
        // 前20%时间：从0到30%，使用easeOutQuad
        const t = elapsedSeconds / stage1Time;
        progressPercent = 30 * (t * (2 - t));
      } else if (elapsedSeconds <= stage1Time + stage2Time) {
        // 接下来40%时间：从30%到93%，使用easeInOutCubic
        const t = (elapsedSeconds - stage1Time) / stage2Time;
        progressPercent = 30 + 63 * (t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2);
      } else {
        // 最后40%时间：从93%到目标进度，使用easeOutQuart
        const t = (elapsedSeconds - stage1Time - stage2Time) / stage3Time;
        progressPercent = 93 + (props.targetProgress - 93) * (1 - Math.pow(1 - t, 4));
      }

      // 确保进度不超过目标值
      progressPercent = Math.min(progressPercent, props.targetProgress);
      progress.value = Math.floor(progressPercent);

      // 如果到达目标或超时，停止动画
      if (elapsed >= duration.value) {
        progress.value = props.targetProgress;
        stopAnimation();
        emit('finish');
      }
    }, 16);
  };

  // 停止进度动画
  const stopAnimation = () => {
    if (progressTimer.value) {
      clearInterval(progressTimer.value);
      progressTimer.value = null;
    }
  };

  // 重置进度
  const reset = () => {
    stopAnimation();
    progress.value = 0;
  };

  // 暴露方法给父组件
  defineExpose({
    startAnimation,
    stopAnimation,
    reset,
  });

  onMounted(() => {
    // 组件挂载时，如果autoStart为true则自动开始动画
    if (props.autoStart) {
      startAnimation();
    }
  });

  // 组件卸载时清除定时器
  onUnmounted(() => {
    stopAnimation();
  });
</script>

<style scoped lang="scss">
  .progress-display {
    background: rgba(0, 0, 0, 0.2);
    color: white;
    padding: 4px 12px;
    border-radius: 16px;
    font-size: 14px;
    font-weight: 500;
    width: 52px;
    text-align: center;
    z-index: 10;
  }
</style>
